#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <stdlib.h>
#include "hypervisor_defs.h"
#include "dom0_ops.h"
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY)
-/* Round _n up to nearest multiple of _m. */
-#define ROUND_UP(_n,_m) (((_n) + (_m) - 1) / (_m))
-
/* standardized error reporting function */
static void dberr(char *msg)
{
close(fd);
goto out;
}
- *ksize = stat.st_size - SIG_LEN;
read(fd, signature, SIG_LEN);
if(strncmp(signature, GUEST_SIG, SIG_LEN)){
read(fd, load_addr, sizeof(unsigned long));
+ *ksize = stat.st_size - SIG_LEN - sizeof(unsigned long);
+
sprintf(status, "Kernel image %s valid, kernel virtual load address %lx",
image, *load_addr);
dbstatus(status);
int cmd_fd;
meminfo = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t));
- page_array = (unsigned long *)dom_mem->vaddr;
+ page_array = malloc(dom_mem->tot_pages * 4);
pgt_updates = (page_update_request_t *)dom_mem->vaddr;
alloc_index = dom_mem->tot_pages - 1;
+ memcpy(page_array, (void *)dom_mem->vaddr, dom_mem->tot_pages * 4);
+
/* Count bottom-level PTs, rounding up. Include one PTE for shared info. */
- num_pt_pages = ROUND_UP(l1_table_offset(virt_load_addr) +
- dom_mem->tot_pages + 1, 1024);
+ num_pt_pages =
+ (l1_table_offset(virt_load_addr) + dom_mem->tot_pages + 1024) / 1024;
+
/* We must also count the page directory. */
num_pt_pages++;
pgt_updates++;
num_pgt_updates++;
- /* Initialise the page tables. */
+ /*
+ * Initialise the page tables. The final iteration is for the shared_info
+ * PTE -- we break out before filling in the entry, as that is done by
+ * Xen during final setup.
+ */
l2tab += l2_table_offset(virt_load_addr) * sizeof(l2_pgentry_t);
- for ( count = 0; count < dom_mem->tot_pages; count++ )
+ for ( count = 0; count < (dom_mem->tot_pages + 1); count++ )
{
if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
{
num_pgt_updates++;
l2tab += sizeof(l2_pgentry_t);
}
+
+ /* The last PTE we consider is filled in later by Xen. */
+ if ( count == dom_mem->tot_pages ) break;
if ( count < pt_start )
{
close(cmd_fd);
/* Load the guest OS image. */
- if(!(read(kernel_fd, (char *)dom_mem->vaddr, ksize) > 0)){
+ if( read(kernel_fd, (char *)dom_mem->vaddr, ksize) != ksize )
+ {
dberr("Error reading kernel image, could not"
" read the whole image. Terminating.\n");
goto out;
int ret = 0;
struct proc_dir_entry * new_dom_id;
dom0_newdomain_t * params;
-
+ int i;
+ unsigned long p;
copy_from_user(&op, buffer, sizeof(dom0_op_t));
}
else if ( op.cmd == DO_PGUPDATES )
{
- ret = HYPERVISOR_pt_update((void *)op.u.pgupdate.pgt_update_arr,
- op.u.pgupdate.num_pgt_updates);
+ p = op.u.pgupdate.pgt_update_arr;
+ for ( i = 0; i < op.u.pgupdate.num_pgt_updates; i++ )
+ {
+ ret = HYPERVISOR_pt_update(p + i*8, 1);
+ }
}
else
{